home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / asmutil / bluebook.zip / FLOATPT.ASM < prev    next >
Assembly Source File  |  1986-05-14  |  23KB  |  843 lines

  1.                                       COMMENT ~
  2. FLOATPT.ASM -- Floating Point Conversion Procedures
  3.  
  4.    From `BLUEBOOK of ASSEMBLY ROUTINES for the IBM PC & XT'
  5.          by Christopher L. Morgan
  6.          Copyright (C) 1984 by The Waite Group, Inc.
  7.  
  8.    Purpose:
  9.  
  10.    Contents:
  11.    ---------
  12.    BIN802DEC    --  Convert from 80-bit binary to decimal digits
  13.    DECDOUBLE    --  Double a temporary decimal floating point number
  14.    DECHALF    --  Halve a temporary decimal floating point number
  15.    DECNORM    --  Normalize temporary decimal floating point
  16.    DFP2SFP    --  Convert from double to single precision floating point
  17.    FIX        --  Convert from floating point to 16-bit integer
  18.    FLOAT    --  Convert from 16-bit integer to floating point
  19.    FPIN        --  Convert from external to internal floating point
  20.    FPINDIGIT    --  Input single decimal digit to floating point
  21.    FPOUT    --  Convert from internal to external floating point
  22.    FPTDIV    --  Divide temporary floating point by 10
  23.    FPTMUL    --  Multiply temporary floating point by 10
  24.    FPTNORM    --  Normalize temporary floating point
  25.    SFP2DFP    --  Convert from single to double precision floating point
  26.    SFP2TFP    --  Convert from single precision to temporary floating point
  27.    SGNDEC16IN    --  Convert from ASCII signed decimal to binary
  28.    TDECSHOW    --  Display floating point
  29.    TFP2SFP    --  Convert from temporary floating point to single precision
  30.  _____________________________________________________________________________
  31.                                                                               ~
  32. CODES    SEGMENT
  33.  
  34.     EXTRN    STDIN:FAR,STDOUT:FAR
  35.     
  36.     PUBLIC SGNDEC16IN,TFP2SFP,FPINDIGIT,FPTNORM,FPTMUL,FPTDIV,FPIN
  37.     PUBLIC SFP2TFP,TDECSHOW,BIN802DEC,DECNORM,DECHALF,DECDOUBLE,FPOUT
  38.     PUBLIC    FIX,FLOAT,SFP2DFP,DFP2SFP,MBINADD,MBINSUB,MBINMUL,MBINDIV
  39.  
  40. ASSUME CS:CODES,DS:DATAS
  41.  
  42. ;Equates
  43.     SIBYTE    EQU    BYTE PTR [SI]
  44.     SIWORD    EQU    WORD PTR [SI]
  45.     DIBYTE  EQU    BYTE PTR [DI]
  46.     DIWORD    EQU    WORD PTR [DI]
  47.  
  48.     SFPBUFFW0    EQU    WORD PTR SFPBUFF+0
  49.     SFPBUFFB2    EQU    BYTE PTR SFPBUFF+2
  50.     SFPBUFFB3    EQU    BYTE PTR SFPBUFF+3
  51.     SFPBUFFW2    EQU    WORD PTR SFPBUFF+2
  52.  
  53.     DFPBUFFW0    EQU    WORD PTR DFPBUFF+0
  54.     DFPBUFFW2    EQU    WORD PTR DFPBUFF+2
  55.     DFPBUFFW4    EQU    WORD PTR DFPBUFF+4
  56.     DFPBUFFW6    EQU    WORD PTR DFPBUFF+6
  57.  
  58.     FPTEMP1W0    EQU    WORD PTR FPTEMP1+0
  59.     FPTEMP1W2    EQU    WORD PTR FPTEMP1+2
  60.     FPTEMP1W4    EQU    WORD PTR FPTEMP1+4
  61.     FPTEMP1W6    EQU    WORD PTR FPTEMP1+6
  62.     FPTEMP1W8    EQU    WORD PTR FPTEMP1+8
  63.     FPTEMP1B10    EQU    BYTE PTR FPTEMP1+10
  64.     FPTEMP1W11    EQU    WORD PTR FPTEMP1+11
  65.  
  66.     FPTEMP2W0    EQU    WORD PTR FPTEMP2+0
  67.     FPTEMP2W2    EQU    WORD PTR FPTEMP2+2
  68.     FPTEMP2W4    EQU    WORD PTR FPTEMP2+4
  69.     FPTEMP2W6    EQU    WORD PTR FPTEMP2+6
  70.     FPTEMP2W8    EQU    WORD PTR FPTEMP2+8
  71.     FPTEMP2B10    EQU    BYTE PTR FPTEMP2+10
  72.     FPTEMP2W11    EQU    WORD PTR FPTEMP2+11
  73.  
  74. ;__________________________ FLOATING POINT ROUTINES __________________________
  75. ;-----------------------------------------------------------------------------
  76. ;Convert from 80-bit binary to decimal digits
  77. BIN802DEC    PROC    NEAR
  78. ;
  79. ;Clear the string
  80.     PUSH    DI                ;Save destination pointer
  81.     MOV    AL,0                ;Zero byte
  82.     MOV    CX,25                ; for a count of 25
  83. BIN802DEC1:
  84.     MOV    [DI],AL                ;Zero the byte
  85.     INC    DI                ;Point to next byte
  86.     LOOP    BIN802DEC1            ; until done
  87.     POP    DI                ;Restore destination pointer
  88. ;
  89. ;Keep looping
  90. BIN802DEC2:
  91.     PUSH    SI                ;Save source pointer
  92. ;
  93. ;Divide mantissa by 10
  94.     MOV    BX,0                ;Done flag
  95.     MOV    CX,5                ;5 words in number
  96.     MOV    DX,0                ;Previous remainder
  97.     ADD    SI,8                ;Point to high end
  98. BIN802DEC3:
  99.     PUSH    CX                ;Save count
  100.     MOV    AX,[SI]                ;Get 16-bit digit
  101.     MOV    CX,10                ;Divisor of 10
  102.     DIV    CX                ;Divide
  103.     MOV    [SI],AX                ;Put 16-bit digit back
  104.     OR    BX,AX                ;Check for zero
  105.     SUB    SI,2                ;Point to next 16-bit digit
  106.     POP    CX                ;Restore count
  107.     LOOP    BIN802DEC3
  108.     MOV    [DI],DL                ;Remainder is decimal digit
  109.     INC    DI                ;Point to next decimal digit
  110.     POP    SI                ;Restore source pointer
  111.     CMP    BX,0                ;Was the binary zero ?
  112.     JNZ    BIN802DEC2            ; if so, loop
  113.     RET                    ; else return
  114. BIN802DEC    ENDP
  115. ;-----------------------------------------------------------------------------
  116. ;Double a temporary decimal floating point number
  117. DECDOUBLE    PROC    NEAR
  118.     MOV    CX,25                ;For a count of 25
  119.     MOV    AH,0                ;Clear previous carry
  120. DECDOUBLE1:
  121.     MOV    AL,[DI]                ;Get digit
  122.     SAL    AL,1                ;Multiply by 2
  123.     ADD    AL,AH                ;Add the carry
  124.     AAM                    ;Adjust for dec multiplication
  125.     MOV    [DI],AL                ;Put the byte back
  126.     INC    DI                ;Point to next byte
  127.     LOOP    DECDOUBLE1
  128.     RET
  129. DECDOUBLE    ENDP
  130. ;-----------------------------------------------------------------------------
  131. ;Halve a temporary decimal floating point number
  132. DECHALF    PROC    NEAR
  133. ;
  134. ;First shift up one digit
  135.     MOV    CX,25                ;For a count of 25
  136.     MOV    AL,0                ;Zero previous digit
  137. DECHALF1:
  138.     XCHG    AL,[DI]                ;Exchange with current digit
  139.     INC    DI                ;Point to next digit
  140.     LOOP    DECHALF1
  141.     DEC    DECEXP                ;Decrement decimal digit
  142. ;
  143. ;Now divide by 2
  144.     MOV    CX,25                ;For a count of 25
  145.     MOV    AH,0                ;Clear carry
  146. DECHALF2:
  147.     PUSH    CX                ;Save count
  148.     DEC    DI                ;Point to next digit
  149.     MOV    AL,[DI]                ;Get the digit
  150.     MOV    CL,2                ;Divisor of 2
  151.     AAD                    ;Adjust for decimal division
  152.     DIV    CL                ;Divide
  153.     MOV    [DI],AL                ;Put it back
  154.     POP    CX                ;Restore count
  155.     LOOP    DECHALF2
  156.     RET
  157. DECHALF        ENDP
  158. ;-----------------------------------------------------------------------------
  159. ;Normalize a temporary decimal floating point number
  160. DECNORM    PROC    NEAR
  161. ;
  162. ;Check top + 1 digit
  163.     CMP    DIBYTE+22,0            ;Is it already zero ?
  164.     JE    DECNORM_XIT            ;If so, go
  165. ;
  166. ;Round up, starting with bottom digit
  167.     MOV    AL,[DI]                ;First digit
  168.     ADD    AL,AL                ;Double it for rounding
  169.     MOV    AH,0                ;Prepare carry
  170.     AAA                    ;Adjust for decimal
  171. ;
  172. ;Now shift the rest
  173.     MOV    CX,24                ;For a count of 24
  174. DECNORM1:
  175.     MOV    AL,[DI+1]            ;Get next digit
  176.     ADD    AL,AH                ;Add carry
  177.     MOV    AH,0                ;Prepare next carry
  178.     AAA                    ;Adjust for decimal
  179.     MOV    [DI],AL                ;Put digit in place
  180.     INC    DI                ;Point to next digit
  181.     LOOP    DECNORM1
  182.     INC    DECEXP                ;Increment decimal exponent
  183. DECNORM_XIT:
  184.     RET
  185. DECNORM        ENDP
  186. ;-----------------------------------------------------------------------------
  187. ;Convert from double to single precision floating point
  188. DFP2SFP    PROC    FAR
  189.     PUSH    AX                ;Save register
  190.     MOV    AX,DFPBUFFW4            ;Get word from double precision
  191.     MOV    SFPBUFFW0,AX            ;Put it in single precision
  192.     MOV    AX,DFPBUFFW6            ;Get word from double precision
  193.     MOV    SFPBUFFW2,AX            ;Put it in single precision
  194.     PUSH    AX                ;Restore register
  195.     RET
  196. DFP2SFP        ENDP
  197. ;-----------------------------------------------------------------------------
  198. ;Convert from internal floating point to internal 16-bit integer (truncate)
  199. FIX    PROC    FAR
  200. ;
  201. ;The number is in SFPBUFF
  202.     PUSH    CX                ;Save registers
  203.     PUSH    AX
  204. ;
  205. ;Get the mantissa
  206.     MOV    AX,SFPBUFFW0            ;AX gets low part
  207.     MOV    AX,SFPBUFFW2            ;DX gets high part
  208.     AND    DX,007FH            ;Just the mantissa
  209.     OR    DX,0080H            ;Restore the MSB
  210. ;
  211. ;Get the exponent
  212.     MOV    CL,SFPBUFFB3            
  213.     MOV    CH,0                ;Extend to 16-bit
  214.     SUB    CX,88H                ;Subtract bias +
  215.     CMP    CX,0                ;Check its sign
  216.     JL    FIX1                ; if negative
  217.     JG    FIX3                ; if positive
  218.     JE    FIX4                ; if zero
  219. ;
  220. ;Shift right
  221. FIX1:
  222.     NEG    CX                ;Absolute value
  223. FIX2:
  224.     SAR    DX,1                ;Shift all bits right
  225.     RCR    AX,1                ;Carry on
  226.     LOOP    FIX2
  227.     JMP    FIX4                ;End of case negative
  228. ;
  229. ;Shift left
  230. FIX3:
  231.     SAL    AX,1                ;Shift all bits left
  232.     RCL    DX,1                ;Carry on
  233.     LOOP    FIX3
  234.     JMP    FIX4                ;End of case positive
  235. ;
  236. ;Check the sign
  237. FIX4:
  238.     MOV    AL,SFPBUFFB2            ;Get sign
  239.     AND    AL,80H                ;Just bit 7
  240.     JZ    FIX_XIT                ;Is it on ?
  241.     NEG    DX                ;Two's complement if negative
  242. ;
  243. FIX_XIT:
  244.     POP    AX                ;Restore registers
  245.     POP    CX
  246.     RET
  247. FIX        ENDP
  248. ;-----------------------------------------------------------------------------
  249. ;Convert from 16-bit integer to floating point
  250. FLOAT    PROC    FAR
  251. ;
  252. ;The number is in DX
  253.     PUSH    DX                ;Save registers
  254.     PUSH    CX        
  255.     PUSH    AX
  256.     MOV    AX,0                ;Extend to 32 bits
  257.     CMP    DX,0                ;Check if zero
  258.     JZ    FLOAT4
  259. FLOAT1:
  260.     MOV    CX,9800H            ;Initialize exponent & sign
  261. ;
  262. ;Shift left until normalized
  263. FLOAT2:
  264.     TEST    AX,0080H            ;Done yet ?
  265.     JNZ    FLOAT3                ;If so, go
  266.     SAL    DX,1                ;If not, shift all bits left
  267.     RCL    AX,1                ;Carry on
  268.     DEC    CH                ;Decrement the exponent
  269.     JMP    FLOAT2
  270. ;
  271. ;Pack it in
  272. FLOAT3:
  273.     AND    AX,007FH            ;Just the mantissa
  274.     OR